package org.shana.springframework.test.explore;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Star {
    String sing();
    void dance();
}

class RealStar implements Star {
    @Override
    public String sing() {
        System.out.println("Real star is singing...");
        return "sing..";
    }

    @Override
    public void dance() {
        System.out.println("Real star is dancing...");
    }
}

class StarHandler implements InvocationHandler {
    private Star realStar;

    public StarHandler(Star realStar) {
        this.realStar = realStar;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Enhancement before method execution");
        Object result = method.invoke(realStar, args);
        System.out.println("Enhancement after method execution");
        return result;
    }
}

public class DynamicProxyDemo {
    public static void main(String[] args) {
        Star realStar = new RealStar();
        StarHandler handler = new StarHandler(realStar);

        Star proxy = (Star) Proxy.newProxyInstance(
                realStar.getClass().getClassLoader(),
                realStar.getClass().getInterfaces(),
                handler
        );

        proxy.sing();
        proxy.dance();
    }
}